package tk.mystudio.ocr;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.imageio.ImageIO;

/**
 * @author Administrator
 *
 */
public class OCRTest {
    private final static String LANG_OPTION = "-l";
    private final static String IMAGE_EXT = "tif";
    private final static String EOL = System.getProperty("line.separator");
    private static String tessPath = new File("tesseract").getAbsolutePath();

	public static String read(String fileName) {
		File file = new File("tesseract", fileName);
		String randCode = "";
		try {
			randCode = read(file);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// file.delete();
		}
		randCode = randCode.replaceAll("\\s", "");
		return randCode;
	}

    private static String read(File imageFile) throws Exception {
        String result = "";
        BufferedImage buffImg = ImageIO.read(imageFile);
        if(buffImg == null) {
        	//System.out.println("tk.mystudio.ocr.OCR 60 line occur problem...");
        	return result;
        }
        //logPointRange(buffImg);
        greyImage(buffImg);
        twoValueImage(buffImg);
        logPointRange(buffImg);
        //MyImgFilter myImgFilter = new MyImgFilter(buffImg);
        //myImgFilter.changeGrey();
        //myImgFilter.getGrey();
        //myImgFilter.getBrighten();
        //buffImg = myImgFilter.getProcessedImg();
        //BufferedImage buffImgTemp = createEmptyImage(buffImg, buffImg.getWidth(null), buffImg.getHeight(null));
        //copyTempImgToNewbuffImg(buffImg, buffImgTemp);
        //buffImg = buffImgTemp;
        //logPointRange(buffImg);
        //twoValueImage(buffImg);
        //logPointRange(buffImg);
        //cleanAlongPointImage(buffImg);
        //logPointRange(buffImg);
        //cleanStrangePointImage(buffImg);
		//logPointRange(buffImg);
		//int width = buffImg.getWidth();
		//int height = buffImg.getHeight();
		//buffImg = resize(buffImg, (int) (width * 1.5), (int) (height * 1.5));
        //logPointRange(buffImg);
        BufferedImage newcleanbuffImg = createEmptyImage(buffImg, buffImg.getWidth() * 2, buffImg.getHeight());
        splitAndCleanImgToNew(buffImg, newcleanbuffImg);
        logPointRange(newcleanbuffImg);
        //BufferedImage newcenterbuffImg = createEmptyImage(buffImg, buffImg.getWidth() * 2, buffImg.getHeight());
        //splitAndFixAndCenterImgToNew(newcleanbuffImg, newcenterbuffImg);
        //logPointRange(newcenterbuffImg);
        BufferedImage newcenterbuffImg = createEmptyImage(buffImg, buffImg.getWidth() * 2, buffImg.getHeight());
        combineAndCenterBuffImgsToNew(splitbuffImgs(newcleanbuffImg), newcenterbuffImg);
        logPointRange(newcenterbuffImg);

        boolean status = ImageIO.write(newcenterbuffImg, IMAGE_EXT, new File(imageFile.getParentFile(), imageFile.getName() + "." + IMAGE_EXT));

        File outputFile = new File(imageFile.getParentFile(), "output");
        StringBuffer strB = new StringBuffer();

        List<String> cmd = new ArrayList<String>();
        cmd.add(tessPath + "\\tesseract");
        cmd.add("");
        cmd.add(outputFile.getName());
        cmd.add(LANG_OPTION);
        cmd.add("eng");
        //cmd.add("randcode");
        //cmd.add("nobatch");
        cmd.add("digitsandalphabets");

        ProcessBuilder pb = new ProcessBuilder(new String[0]);
        pb.directory(imageFile.getParentFile());
        if (status)
            cmd.set(1, imageFile.getName() + "." + IMAGE_EXT);
        else
            cmd.set(1, imageFile.getName());
        pb.command(cmd);
        pb.redirectErrorStream(true);
        Process process = pb.start();
        int w = process.waitFor();
        if (w == 0) {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath() + ".txt"), "UTF-8"));
            String str;
            while ((str = in.readLine()) != null) {
                strB.append(str).append(EOL);
            }
            in.close();
        } else {
            String msg;
            switch (w) {
            case 1:
                msg = "Errors accessing files. There may be spaces in your image's filename.";
                break;
            case 29:
                msg = "Cannot recognize the image or its selected region.";
                break;
            case 31:
                msg = "Unsupported image format.";
                break;
            default:
                msg = "Errors occurred.";
            }
            throw new RuntimeException(msg);
		}
		new File(outputFile.getAbsolutePath() + ".txt").delete();
		// new File(imageFile.getAbsolutePath() + "." + IMAGE_EXT).delete();
		result = strB.toString().trim();
		return result;
	}

    /**
     * 将所有分好层的图层拷贝到新图层，居中显示
     * @param buffImg 现有图层
     * @param newbuffImg 新图层
     * @return
     */
    private static void combineAndCenterBuffImgsToNew(List<Map<Boundary, BufferedImage>> buffImgs, BufferedImage newbuffImg) {
        int lastnewX = 0;
        for (Iterator<Map<Boundary, BufferedImage>> iter = buffImgs.iterator(); iter.hasNext();) {
            Map<Boundary, BufferedImage> buffImgMap = iter.next();
            Boundary bound = buffImgMap.keySet().iterator().next();
            BufferedImage tempbuffImg = buffImgMap.get(bound);
            lastnewX = copyTempImgToNewbuffImg(tempbuffImg, newbuffImg, bound, lastnewX);
        }
    }
    
    /**
     * 将现有图层分层
     * @param buffImg 现有图层
     * @param newbuffImg 新图层
     * @return
     */
    private static List<Map<Boundary, BufferedImage>> splitbuffImgs(BufferedImage buffImg) {
        List<Map<Boundary, BufferedImage>> returnbuffImgs = new ArrayList<Map<Boundary, BufferedImage>>();
        List<Map<Boundary, BufferedImage>> buffImgs = new ArrayList<Map<Boundary, BufferedImage>>();
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        boolean flag = true;
        Map<Integer, Map<String, Object>> cacheStrangeContinueTempBuffImgMap = new LinkedHashMap<Integer, Map<String, Object>>();
        int i = 0;
        while (flag) {
            Boundary bound = new Boundary();
            BufferedImage tempbuffImg = createEmptyImage(buffImg, buffImg.getWidth(), buffImg.getHeight());
            for (int x = minX; x < width; x++) {
                if (bound.minX != -1) {
                    break;
                }
                for (int y = minY; y < height; y++) {
                    int rgb = buffImg.getRGB(x, y);
                    Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
                    if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
                        bound.minX = bound.maxX = x;
                        bound.minY = bound.maxY = y;
                        break;
                    }
                }
            }
            if (bound.minX == -1) {
                flag = false;
            } else {
                cutContinuousCleanPointToTempImg(bound.minX, bound.minY, buffImg, tempbuffImg, bound);
                Map<String, Object> itemmap = new HashMap<String, Object>();
                itemmap.put("bound", bound);
                itemmap.put("tempbuffImg", tempbuffImg);
                cacheStrangeContinueTempBuffImgMap.put(i++, itemmap);
            }
        }
        Entry<Integer, Map<String, Object>> lastEntry = null;
        for (Iterator<Entry<Integer, Map<String, Object>>> iter = cacheStrangeContinueTempBuffImgMap.entrySet().iterator(); iter.hasNext();) {
            Entry<Integer, Map<String, Object>> entry = iter.next();
            BufferedImage tempbuffImg = (BufferedImage) entry.getValue().get("tempbuffImg");
            Boundary bound = (Boundary) entry.getValue().get("bound");
            boolean isrelateToNext = false;
            if (iter.hasNext()) {
                isrelateToNext = true;
            }
            boolean isrelateToLast = false;
            if (lastEntry != null) {
                BufferedImage lastTempbuffImg = (BufferedImage) lastEntry.getValue().get("tempbuffImg");
                Boundary lastBound = (Boundary) lastEntry.getValue().get("bound");
                int vdistance = calTwoBuffImgDistance(lastTempbuffImg, tempbuffImg, 1);
                int ldistance = calTwoBuffImgDistance(lastTempbuffImg, tempbuffImg, 2);
                if (vdistance < 4 || ldistance < 2) {
                    isrelateToLast = true;
                }
                if (isrelateToLast) {
                    copyTempImgToNewbuffImg(lastTempbuffImg, tempbuffImg);
                    bound.maxX = (bound.maxX > lastBound.maxX) ? bound.maxX : lastBound.maxX;
                    bound.maxY = (bound.maxY > lastBound.maxY) ? bound.maxY : lastBound.maxY;
                    bound.minX = (bound.minX < lastBound.minX) ? bound.minX : lastBound.minX;
                    bound.minY = (bound.minY < lastBound.minY) ? bound.minY : lastBound.minY;
                } else {
                    Map<Boundary, BufferedImage> buffImgMap = new LinkedHashMap<Boundary, BufferedImage>();
                    buffImgMap.put(lastBound, lastTempbuffImg);
                    buffImgs.add(buffImgMap);
                }
            }
            if (!isrelateToNext) {
                Map<Boundary, BufferedImage> buffImgMap = new LinkedHashMap<Boundary, BufferedImage>();
                buffImgMap.put(bound, tempbuffImg);
                buffImgs.add(buffImgMap);
                lastEntry = null;
            } else {
                lastEntry = entry;
            }
        }
        int buffSize = buffImgs.size();
        if (buffSize < 4) {//小于四个图层时,格式化为四个图层
            int actualWidth = 0;//字符实际所占宽
            for (Map<Boundary, BufferedImage> buffImgMap : buffImgs) {
                if (buffImgMap.size() > 0) {
                    actualWidth += buffImgMap.keySet().iterator().next().getWidth();
                }
            }
            if(buffSize == 1) {
                Map<Boundary, BufferedImage> buffImgMap0 = buffImgs.get(0);
                Boundary bound0 = buffImgMap0.keySet().iterator().next();
                BufferedImage buffImg0 = buffImgMap0.get(bound0);
                int num0 = 4;
                List<Map<Boundary, BufferedImage>> itemBuffImgs0 = splitBuffImgByMinHeight(buffImg0, bound0, actualWidth, num0);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs0) {
                    returnbuffImgs.add(buffImgMap);
                }
                
            } else if(buffSize == 2) {
                Map<Boundary, BufferedImage> buffImgMap0 = buffImgs.get(0);
                Boundary bound0 = buffImgMap0.keySet().iterator().next();
                BufferedImage buffImg0 = buffImgMap0.get(bound0);
                int num0 = (int) ((bound0.getWidth() * 4.0 / actualWidth) + 0.125);
                List<Map<Boundary, BufferedImage>> itemBuffImgs0 = splitBuffImgByMinHeight(buffImg0, bound0, actualWidth, num0);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs0) {
                    returnbuffImgs.add(buffImgMap);
                }
                
                Map<Boundary, BufferedImage> buffImgMap1 = buffImgs.get(1);
                Boundary bound1 = buffImgMap1.keySet().iterator().next();
                BufferedImage buffImg1 = buffImgMap1.get(bound1);
                int num1 = 4 - num0;
                List<Map<Boundary, BufferedImage>> itemBuffImgs1 = splitBuffImgByMinHeight(buffImg1, bound1, actualWidth, num1);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs1) {
                    returnbuffImgs.add(buffImgMap);
                }
                
            } else if(buffSize == 3) {
                Map<Boundary, BufferedImage> buffImgMap0 = buffImgs.get(0);
                Boundary bound0 = buffImgMap0.keySet().iterator().next();
                BufferedImage buffImg0 = buffImgMap0.get(bound0);
                int num0 = (int) ((bound0.getWidth() * 4.0 / actualWidth) + 0.125);
                List<Map<Boundary, BufferedImage>> itemBuffImgs0 = splitBuffImgByMinHeight(buffImg0, bound0, actualWidth, num0);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs0) {
                    returnbuffImgs.add(buffImgMap);
                }
                
                Map<Boundary, BufferedImage> buffImgMap1 = buffImgs.get(1);
                Boundary bound1 = buffImgMap1.keySet().iterator().next();
                BufferedImage buffImg1 = buffImgMap1.get(bound1);
                int num1 = (int) ((bound1.getWidth() * 4.0 / actualWidth) + 0.125);
                List<Map<Boundary, BufferedImage>> itemBuffImgs1 = splitBuffImgByMinHeight(buffImg1, bound1, actualWidth, num1);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs1) {
                    returnbuffImgs.add(buffImgMap);
                }
                
                Map<Boundary, BufferedImage> buffImgMap2 = buffImgs.get(2);
                Boundary bound2 = buffImgMap2.keySet().iterator().next();
                BufferedImage buffImg2 = buffImgMap2.get(bound2);
                int num2 = 4  - num0 - num1;
                List<Map<Boundary, BufferedImage>> itemBuffImgs2 = splitBuffImgByMinHeight(buffImg2, bound2, actualWidth, num2);
                for(Map<Boundary, BufferedImage> buffImgMap : itemBuffImgs2) {
                    returnbuffImgs.add(buffImgMap);
                }
                
            }
        } else {
            for(Map<Boundary, BufferedImage> buffImgMap : buffImgs) {
                returnbuffImgs.add(buffImgMap);
            }
        }
        return returnbuffImgs;
    }
    
    /**
     * 将缓存图根据实际宽找出最小垂直系数划分成num份缓存图
     * @param buffImgMap
     * @param width
     * @param num
     * @return
     */
    private static List<Map<Boundary, BufferedImage>> splitBuffImgByMinHeight(BufferedImage buffImg, Boundary bound, int width, int num) {
        List<Map<Boundary, BufferedImage>> returnbuffImgs = new ArrayList<Map<Boundary, BufferedImage>>();
        if(num == 4) {
            int start0 = bound.minX + bound.getWidth() / 8 + 2;
            int end0 = start0 + bound.getWidth() / 4 - 2;
            int xIndex0 = findXByMinHeight(buffImg, bound, start0, end0);
            Boundary bound0 = new Boundary();
            bound0.minX = bound.minX;
            bound0.maxX = xIndex0 - 1;
            bound0.minY = bound.minY;
            bound0.maxY = bound.maxY;
            BufferedImage buffImg0 = cutBuffImgByXrange(buffImg, bound0);
            Map<Boundary, BufferedImage> buffImgMap0 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap0.put(bound0, buffImg0);
            returnbuffImgs.add(buffImgMap0);
            
            int start1 = end0 + 2;
            int end1 = start1 + bound.getWidth() / 4 - 2;
            int xIndex1 = findXByMinHeight(buffImg, bound, start1, end1);
            Boundary bound1 = new Boundary();
            bound1.minX = xIndex0 + 1;
            bound1.maxX = xIndex1 - 1;
            bound1.minY = bound.minY;
            bound1.maxY = bound.maxY;
            BufferedImage buffImg1 = cutBuffImgByXrange(buffImg, bound1);
            Map<Boundary, BufferedImage> buffImgMap1 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap1.put(bound1, buffImg1);
            returnbuffImgs.add(buffImgMap1);
            
            int start2 = end1 + 2;
            int end2 = start2 + bound.getWidth() / 4 - 2;
            int xIndex2 = findXByMinHeight(buffImg, bound, start2, end2);
            Boundary bound2 = new Boundary();
            bound2.minX = xIndex1 + 1;
            bound2.maxX = xIndex2 - 1;
            bound2.minY = bound.minY;
            bound2.maxY = bound.maxY;
            BufferedImage buffImg2 = cutBuffImgByXrange(buffImg, bound2);
            Map<Boundary, BufferedImage> buffImgMap2 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap2.put(bound2, buffImg2);
            returnbuffImgs.add(buffImgMap2);
            
            Boundary bound3 = new Boundary();
            bound3.minX = xIndex2 + 1;
            bound3.maxX = bound.maxX;
            bound3.minY = bound.minY;
            bound3.maxY = bound.maxY;
            BufferedImage buffImg3 = cutBuffImgByXrange(buffImg, bound3);
            Map<Boundary, BufferedImage> buffImgMap3 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap3.put(bound3, buffImg3);
            returnbuffImgs.add(buffImgMap3);
            
        } else if(num == 3) {
            int start0 = bound.minX + bound.getWidth() / 6 + 2;
            int end0 = start0 + bound.getWidth() / 3 - 2;
            int xIndex0 = findXByMinHeight(buffImg, bound, start0, end0);
            Boundary bound0 = new Boundary();
            bound0.minX = bound.minX;
            bound0.maxX = xIndex0 - 1;
            bound0.minY = bound.minY;
            bound0.maxY = bound.maxY;
            BufferedImage buffImg0 = cutBuffImgByXrange(buffImg, bound0);
            Map<Boundary, BufferedImage> buffImgMap0 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap0.put(bound0, buffImg0);
            returnbuffImgs.add(buffImgMap0);
            
            int start1 = end0 + 2;
            int end1 = start1 + bound.getWidth() / 3 - 2;
            int xIndex1 = findXByMinHeight(buffImg, bound, start1, end1);
            Boundary bound1 = new Boundary();
            bound1.minX = xIndex0 + 1;
            bound1.maxX = xIndex1 - 1;
            bound1.minY = bound.minY;
            bound1.maxY = bound.maxY;
            BufferedImage buffImg1 = cutBuffImgByXrange(buffImg, bound1);
            Map<Boundary, BufferedImage> buffImgMap1 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap1.put(bound1, buffImg1);
            returnbuffImgs.add(buffImgMap1);
            
            Boundary bound2 = new Boundary();
            bound2.minX = xIndex1 + 1;
            bound2.maxX = bound.maxX;
            bound2.minY = bound.minY;
            bound2.maxY = bound.maxY;
            BufferedImage buffImg2 = cutBuffImgByXrange(buffImg, bound2);
            Map<Boundary, BufferedImage> buffImgMap2 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap2.put(bound2, buffImg2);
            returnbuffImgs.add(buffImgMap2);
            
        } else if (num == 2) {
            int start0 = bound.minX + bound.getWidth() / 4 + 2;
            int end0 = bound.maxX - bound.getWidth() / 4 - 2;
            int xIndex0 = findXByMinHeight(buffImg, bound, start0, end0);
            Boundary bound0 = new Boundary();
            bound0.minX = bound.minX;
            bound0.maxX = xIndex0 - 1;
            bound0.minY = bound.minY;
            bound0.maxY = bound.maxY;
            BufferedImage buffImg0 = cutBuffImgByXrange(buffImg, bound0);
            Map<Boundary, BufferedImage> buffImgMap0 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap0.put(bound0, buffImg0);
            returnbuffImgs.add(buffImgMap0);
            
            Boundary bound1 = new Boundary();
            bound1.minX = xIndex0 + 1;
            bound1.maxX = bound.maxX;
            bound1.minY = bound.minY;
            bound1.maxY = bound.maxY;
            BufferedImage buffImg1 = cutBuffImgByXrange(buffImg, bound1);
            Map<Boundary, BufferedImage> buffImgMap1 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap1.put(bound1, buffImg1);
            returnbuffImgs.add(buffImgMap1);
        } else {
            Map<Boundary, BufferedImage> buffImgMap0 = new LinkedHashMap<Boundary, BufferedImage>();
            buffImgMap0.put(bound, buffImg);
            returnbuffImgs.add(buffImgMap0);
        }
        return returnbuffImgs;
    }
    
	private static BufferedImage cutBuffImgByXrange(BufferedImage buffImg, Boundary bound) {
        BufferedImage tempbuffImg = createEmptyImage(buffImg, buffImg.getWidth(), buffImg.getHeight());
        for (int x = bound.minX; x <= bound.maxX; x++) {
            for (int y = bound.minY; y <= bound.maxY; y++) {
                tempbuffImg.setRGB(x, y, buffImg.getRGB(x, y));
            }
        }
	    return tempbuffImg;
    }

    /**
	 * 找出缓存图中对应横坐标范围内最小垂直系数
	 * @param buffImg
	 * @param bound
	 * @param start
	 * @param end
	 * @return
	 */
	private static int findXByMinHeight(BufferedImage buffImg, Boundary bound, int start, int end) {
	    int xIndex = bound.minX + bound.getWidth()/2;
	    int minYDistance = 10;
	    for(int x = start; x < end; x++) {
	        int minY = 0;
            int maxY = buffImg.getHeight(null);
	        for(int y1 = 0; y1 < buffImg.getHeight(null); y1++) {
	            int rgb = buffImg.getRGB(x, y1);
	            Color color = new Color(rgb);
                if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
                    minY = y1;
                    break;
                }
	        }
            for(int y2 = buffImg.getHeight(null) - 1; y2 >= 0; y2--) {
                int rgb = buffImg.getRGB(x, y2);
                Color color = new Color(rgb);
                if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
                    maxY = y2;
                    break;
                }
            }
            if(maxY - minY < minYDistance) {
                minYDistance = maxY - minY;
                xIndex = x;
            }
	    }
        return xIndex;
    }

    /**
     * 将现有图层拷贝到新图层，并且将不连续的点图分离开来，居中显示
     * @param buffImg 现有图层
     * @param newbuffImg 新图层
     * @return
     */
	private static void splitAndFixAndCenterImgToNew(BufferedImage buffImg, BufferedImage newbuffImg) {
		int height = buffImg.getHeight();
		int width = buffImg.getWidth();
		int minY = 0;
		int minX = 0;
		int lastnewX = 0;
		boolean flag = true;
		Map<Integer, Map<String, Object>> cacheStrangeContinueTempBuffImgMap = new LinkedHashMap<Integer, Map<String, Object>>();
		int i = 0;
		while (flag) {
			Boundary bound = new Boundary();
			BufferedImage tempbuffImg = createEmptyImage(buffImg, buffImg.getWidth(), buffImg.getHeight());
			for (int x = minX; x < width; x++) {
				if (bound.minX != -1) {
					break;
				}
				for (int y = minY; y < height; y++) {
					int rgb = buffImg.getRGB(x, y);
					Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
					if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
						bound.minX = bound.maxX = x;
						bound.minY = bound.maxY = y;
						break;
					}
				}
			}
			if (bound.minX == -1) {
				flag = false;
			} else {
				cutContinuousCleanPointToTempImg(bound.minX, bound.minY, buffImg, tempbuffImg, bound);
				Map<String, Object> itemmap = new HashMap<String, Object>();
				itemmap.put("bound", bound);
				itemmap.put("tempbuffImg", tempbuffImg);
				cacheStrangeContinueTempBuffImgMap.put(i++, itemmap);
			}
		}
		Entry<Integer, Map<String, Object>> lastEntry = null;
		for (Iterator<Entry<Integer, Map<String, Object>>> iter = cacheStrangeContinueTempBuffImgMap.entrySet().iterator(); iter.hasNext();) {
			Entry<Integer, Map<String, Object>> entry = iter.next();
			BufferedImage tempbuffImg = (BufferedImage) entry.getValue().get("tempbuffImg");
			Boundary bound = (Boundary) entry.getValue().get("bound");
			boolean isrelateToNext = false;
			if (iter.hasNext()) {
				isrelateToNext = true;
			}
			boolean isrelateToLast = false;
			if (lastEntry != null) {
				BufferedImage lastTempbuffImg = (BufferedImage) lastEntry.getValue().get("tempbuffImg");
				Boundary lastBound = (Boundary) lastEntry.getValue().get("bound");
				int distance = calTwoBuffImgDistance(lastTempbuffImg, tempbuffImg, 0);
				int vdistance = calTwoBuffImgDistance(lastTempbuffImg, tempbuffImg, 1);
				int ldistance = calTwoBuffImgDistance(lastTempbuffImg, tempbuffImg, 2);
				//if ((vdistance < 2 || ldistance < 2) 
				//		|| (distance < 8 && ((bound.getWidth() < 5 || bound.getHeight() < 5) 
				//		|| (lastBound.getWidth() < 5 || lastBound.getHeight() < 5)))) {
				if (vdistance < 4 || ldistance < 2) {
					isrelateToLast = true;
				}
				if (isrelateToLast) {
					copyTempImgToNewbuffImg(lastTempbuffImg, tempbuffImg);
					bound.maxX = (bound.maxX > lastBound.maxX) ? bound.maxX : lastBound.maxX;
					bound.maxY = (bound.maxY > lastBound.maxY) ? bound.maxY : lastBound.maxY;
					bound.minX = (bound.minX < lastBound.minX) ? bound.minX : lastBound.minX;
					bound.minY = (bound.minY < lastBound.minY) ? bound.minY : lastBound.minY;
				} else {
					lastnewX = copyTempImgToNewbuffImg(lastTempbuffImg, newbuffImg, lastBound, lastnewX);
				}
			}
			if (!isrelateToNext) {
				lastnewX = copyTempImgToNewbuffImg(tempbuffImg, newbuffImg, bound, lastnewX);
				lastEntry = null;
			} else {
				lastEntry = entry;
			}
		}
	}
    
	/**
     * 将现有图层拷贝到新图层，并且将不连续的点图分离开来，居中显示
     * @param buffImg 现有图层
     * @param newbuffImg 新图层
     * @return
     */
	private static void splitAndCenterImgToNew(BufferedImage buffImg, BufferedImage newbuffImg) {
		int height = buffImg.getHeight();
		int width = buffImg.getWidth();
		int minY = 0;
		int minX = 0;
		int lastnewX = 0;
		boolean flag = true;
		int i = 0;
		while (flag) {
			Boundary bound = new Boundary();
			BufferedImage tempbuffImg = createEmptyImage(buffImg, buffImg.getWidth(), buffImg.getHeight());
			for (int x = minX; x < width; x++) {
				if (bound.minX != -1) {
					break;
				}
				for (int y = minY; y < height; y++) {
					int rgb = buffImg.getRGB(x, y);
					Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
					if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
						bound.minX = bound.maxX = x;
						bound.minY = bound.maxY = y;
						break;
					}
				}
			}
			if (bound.minX == -1) {
				flag = false;
			} else {
				cutContinuousCleanPointToTempImg(bound.minX, bound.minY, buffImg, tempbuffImg, bound);
				if(bound.getWidth() > 5 || bound.getHeight() > 5) {
					if ((bound.getWidth() > 4 && bound.getHeight() > 3) || (bound.getWidth() > 3 && bound.getHeight() > 4)) {
						lastnewX = copyTempImgToNewbuffImg(tempbuffImg, newbuffImg, bound, lastnewX);
					}
				}
			}
		}
	}
    
	private static int copyTempImgToNewbuffImg(BufferedImage tempbuffImg, BufferedImage newbuffImg, Boundary bound, int lastnewX) {
		int newheight = newbuffImg.getHeight();
		int newwidth = newbuffImg.getWidth();
		Boundary newbound = new Boundary();
		newbound.minX = lastnewX + 3;
		newbound.minY = 0;
		newbound.maxX = newbound.minX + bound.getWidth() + 3;
		int initnewx = newbound.minX;
		int initnewy = (newheight - bound.maxY + bound.minY) / 2;
		int inittempx = bound.minX;
		int inittempy = bound.minY;
		for (int y = 0; y < bound.getHeight(); y++) {
			for (int x = 0; x < bound.getWidth(); x++) {
				int rgb = tempbuffImg.getRGB(inittempx + x, inittempy + y);
				Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
					newbuffImg.setRGB(initnewx + x, initnewy + y, rgb);
				}
			}
		}
		return newbound.maxX;
	}
    
	/**
     * 将现有图层拷贝到新图层，并且将不连续的点图分离开来，然后去掉小黑点
     * @param buffImg 现有图层
     * @param newbuffImg 新图层
     * @return
     */
	private static void splitAndCleanImgToNew(BufferedImage buffImg, BufferedImage newbuffImg) {
		int height = buffImg.getHeight();
		int width = buffImg.getWidth();
		int minY = 0;
		int minX = 0;
		boolean flag = true;
		while (flag) {
			Boundary bound = new Boundary();
			BufferedImage tempbuffImg = createEmptyImage(buffImg, buffImg.getWidth(), buffImg.getHeight());
			for (int x = minX; x < width; x++) {
				if (bound.minX != -1) {
					break;
				}
				for (int y = minY; y < height; y++) {
					int rgb = buffImg.getRGB(x, y);
					Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
					if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
						bound.minX = bound.maxX = x;
						bound.minY = bound.maxY = y;
						break;
					}
				}
			}
			if (bound.minX == -1) {
				flag = false;
			} else {
				cutContinuousCleanPointToTempImg(bound.minX, bound.minY, buffImg, tempbuffImg, bound);
				if (bound.getWidth() > 4 || bound.getHeight() > 4) {
					copyTempImgToNewbuffImg(tempbuffImg, newbuffImg);
				}
			}
		}
	}
    
	private static void copyTempImgToNewbuffImg(BufferedImage tempbuffImg, BufferedImage newbuffImg) {
		int height = tempbuffImg.getHeight();
		int width = tempbuffImg.getWidth();
		int minY = 0;
		int minX = 0;
		for (int y = minY; y < height; y++) {
			for (int x = minX; x < width; x++) {
				int rgb = tempbuffImg.getRGB(x, y);
				Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
					newbuffImg.setRGB(x, y, rgb);
				}
			}
		}
	}
    
	/**
	 * 计算两张图片的距离
	 * @param buffImg1
	 * @param buffImg2
	 * @param type 类型 实际距离:0;垂直距离:1;水平距离:2;
	 * @return
	 */
	private static int calTwoBuffImgDistance(BufferedImage buffImg1, BufferedImage buffImg2, int type) {
		int height1 = buffImg1.getHeight();
		int width1 = buffImg1.getWidth();
		int height2 = buffImg2.getHeight();
		int width2 = buffImg2.getWidth();
		int minY = 0;
		int minX = 0;
		int length = 100;
		for (int y1 = minY; y1 < height1; y1++) {
			for (int x1 = minX; x1 < width1; x1++) {
				int rgb1 = buffImg1.getRGB(x1, y1);
				Color color1 = new Color(rgb1); // 根据rgb的int值分别取得r,g,b颜色。
				if (color1.getRed() < 180 || color1.getGreen() < 180 || color1.getBlue() < 180) {
					for (int y2 = minY; y2 < height2; y2++) {
						for (int x2 = minX; x2 < width2; x2++) {
							int rgb2 = buffImg2.getRGB(x2, y2);
							Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
							if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
								int tempminlen = 100;
								if (type == 0) {
									if (x1 == x2) {
										tempminlen = Math.abs(y2 - y1);
									}
									if (y1 == y2) {
										tempminlen = Math.abs(x2 - x1);
									}
									if (tempminlen == 100) {
										tempminlen = (int) Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
									}
								} else if (type == 1) {
                                    if (x1 == x2) {
                                        tempminlen = Math.abs(y2 - y1);
                                    }
								} else if (type == 2) {
                                    if (y1 == y2) {
                                        tempminlen = Math.abs(x2 - x1);
                                    }
								}
								if (tempminlen < length) {
									length = tempminlen;
								}
							}
						}
					}
				}
			}
		}
		return length;
	}
    
	/**
	 * 剪切连续点到临时图层
	 * @param x
	 * @param y
	 * @param buffImg
	 * @param tempbuffImg
	 * @param bound
	 */
	private static void cutContinuousCleanPointToTempImg(int x, int y,
			BufferedImage buffImg, BufferedImage tempbuffImg, Boundary bound) {
		int height = buffImg.getHeight();
		int width = buffImg.getWidth();
		int minY = 0;
		int minX = 0;
        buffImg.setRGB(x, y, Color.WHITE.getRGB());
        tempbuffImg.setRGB(x, y, Color.BLACK.getRGB());
		if (x < bound.minX) {
			bound.minX = x;
		}
		if (y < bound.minY) {
			bound.minY = y;
		}
		if (x > bound.maxX) {
			bound.maxX = x;
		}
		if (y > bound.maxY) {
			bound.maxY = y;
		}
		// 直
		if (y > minY) {
			int rgbt = buffImg.getRGB(x, y - 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x, y - 1, buffImg, tempbuffImg, bound);
			}
		}
		if (x > minX) {
			int rgbt = buffImg.getRGB(x - 1, y);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x - 1, y, buffImg, tempbuffImg, bound);
			}
		}
		if (y < height - 1) {
			int rgbt = buffImg.getRGB(x, y + 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x, y + 1, buffImg, tempbuffImg, bound);
			}
		}
		if (x < width - 1) {
			int rgbt = buffImg.getRGB(x + 1, y);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x + 1, y, buffImg, tempbuffImg, bound);
			}
		}
		// 斜
		if (x > minX && y > minY) {
			int rgbt = buffImg.getRGB(x - 1, y - 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x - 1, y - 1, buffImg, tempbuffImg, bound);
			}
		}
		if (x > minX && y < height - 1) {
			int rgbt = buffImg.getRGB(x - 1, y + 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x - 1, y + 1, buffImg, tempbuffImg, bound);
			}
		}
		if (x < width - 1 && y < height - 1) {
			int rgbt = buffImg.getRGB(x + 1, y + 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x + 1, y + 1, buffImg, tempbuffImg, bound);
			}
		}
		if (x < width - 1 && y > minY) {
			int rgbt = buffImg.getRGB(x + 1, y - 1);
			Color color = new Color(rgbt); // 根据rgb的int值分别取得r,g,b颜色。
			if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
				cutContinuousCleanPointToTempImg(x + 1, y - 1, buffImg, tempbuffImg, bound);
			}
		}
	}

	/**
     * 创建一个空白图片
     * @param targetW 目标长
     * @param targetH 目标宽
     * @return
     */
	public static BufferedImage createEmptyImage(BufferedImage source, int targetW, int targetH) {
		BufferedImage target = null;
		int imageType = source.getType();
		if (imageType == BufferedImage.TYPE_CUSTOM) { // handmade
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
		} else {
			target = new BufferedImage(targetW, targetH, imageType);
		}
		int height = target.getHeight();
		int width = target.getWidth();
		int minY = 0;
		int minX = 0;
		for (int y = minY; y < height; y++) {
			for (int x = minX; x < width; x++) {
                target.setRGB(x, y, Color.WHITE.getRGB());
			}
		}
		return target;
	}
    
    
    /**
     * 改变图片的大小
     * @param source 源文件
     * @param targetW 目标长
     * @param targetH 目标宽
     * @return
     */
    public static BufferedImage resize(BufferedImage source, int targetW, int targetH) {
        int type = source.getType();
        BufferedImage target = null;
        double sx = (double) targetW / source.getWidth();
        double sy = (double) targetH / source.getHeight();
        // 这里想实现在targetW，targetH范围内实现等比缩放。如果不需要等比缩放
        // 则将下面的if else语句注释即可
        if (sx > sy) {
            sx = sy;
            targetW = (int) (sx * source.getWidth());
        } else {
            sy = sx;
            targetH = (int) (sy * source.getHeight());
        }
        if (type == BufferedImage.TYPE_CUSTOM) { // handmade
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        } else {
            target = new BufferedImage(targetW, targetH, type);
        }
        Graphics2D g = target.createGraphics();
        // smoother than exlax:
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return target;
    }
	
    /**
     * 打印点阵
     * @return
     */
	private static void logPointRange(BufferedImage buffImg) {
		// test 打印点阵
		int height = buffImg.getHeight();
		int width = buffImg.getWidth();
		int minY = 0;
		int minX = 0;
		for (int y = minY; y < height; y++) {
			for (int x = minX; x < width; x++) {
				int rgb = buffImg.getRGB(x, y);
				Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
					System.out.print('*');
				} else {
					System.out.print(' ');
				}
			}
			System.out.print('\n');
		}
		System.out.println("--------------------------------------------------------------");
	}
    
    
    /**
     * 1.灰度化图片
     * @return
     */
	private static void greyImage(BufferedImage buffImg) {
        // 1.首先灰度化，灰度值=0.3R+0.59G+0.11B：
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        for (int y = minY; y < height; y++) {
            for (int x = minX; x < width; x++) {
                int rgb = buffImg.getRGB(x, y);
                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
                //int gray = (int) (0.3 * color.getRed() + 0.59 * color.getGreen() + 0.11 * color.getBlue());
                //int gray = (int) (0.25 * color.getRed() + 0.65 * color.getGreen() + 0.1 * color.getBlue());
                int gray = (int) (0.25 * color.getRed() + 0.45 * color.getGreen() + 0.3 * color.getBlue());
            	Color newColor = new Color(gray, gray, gray);
            	buffImg.setRGB(x, y, newColor.getRGB());
            }
        }
	}
    
    /**
     * 2.灰度反转图片
     * @deprecated
     * @return
     */
	private static void greyReverseImage(BufferedImage buffImg) {
        // 2.其次是灰度反转：
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        for (int y = minY; y < height; y++) {
            for (int x = minX; x < width; x++) {
                int rgb = buffImg.getRGB(x, y);
                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
                Color newColor = new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
                buffImg.setRGB(x, y, newColor.getRGB());
            }
        }
	}
    
    /**
     * 3.二值化图片
     * @return
     */
	private static void twoValueImage(BufferedImage buffImg) {
        // 3.再次是二值化，取图片的平均灰度作为阈值，低于该值的全都为0，高于该值的全都为255：
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        for (int y = minY; y < height; y++) {
            for (int x = minX; x < width; x++) {
                int rgb = buffImg.getRGB(x, y);
                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
                    buffImg.setRGB(x, y, Color.BLACK.getRGB());
                } else {
                    buffImg.setRGB(x, y, Color.WHITE.getRGB());
                }
            }
        }
	}
    
    /**
     * 5.去噪点
     * @return
     */
	private static void cleanAlongPointImage(BufferedImage buffImg) {
		// 5.去噪点,把有三面以上空白的点给去掉(像素直径径小于1的给去掉)
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        for (int y = minY; y < height; y++) {
            for (int x = minX; x < width; x++) {
                int rgb = buffImg.getRGB(x, y);
                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
					boolean flg = true; // 是否可以去掉该像素
					boolean flgr = true; // 是否可以去掉该像素
					// 获取周边像素
					int side = 0;
					if (y > minY) {
						int rgb2 = buffImg.getRGB(x, y - 1);
		                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
		                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flg = false;
						}
					}
					if (y < height - 1) {
						int rgb2 = buffImg.getRGB(x, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flg = false;
						}
					}
					if (x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flg = false;
						}
					}
					if (x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flg = false;
						}
					}
					if (y > minY && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flgr = false;
						} else {
							side++;
						}
					}
					if (y < height - 1 && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flgr = false;
						} else {
							side++;
						}
					}
					if (y > minY && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flgr = false;
						} else {
							side++;
						}
					}
					if (y < height - 1 && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							flgr = false;
						} else {
							side++;
						}
					}
					if (flg && (flgr || side >= 3)) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
                }
            }
        }
	}
    
    /**
     * 5.1去奇异点
     * @return
     */
	private static void cleanStrangePointImage(BufferedImage buffImg) {
		// 5.1去奇异点,去掉带有突出直角形的点
        int height = buffImg.getHeight();
        int width = buffImg.getWidth();
        int minY = 0;
        int minX = 0;
        for (int y = minY; y < height; y++) {
            for (int x = minX; x < width; x++) {
                int rgb = buffImg.getRGB(x, y);
                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。
				if (color.getRed() < 180 || color.getGreen() < 180 || color.getBlue() < 180) {
					// 获取某一方向像素
					boolean sidee = false;
					boolean sides = false;
					boolean sidew = false;
					boolean siden = false;
					boolean sidees = false;
					boolean sidews = false;
					boolean sideen = false;
					boolean sidewn = false;
					boolean sideei = false;
					boolean sidesi = false;
					boolean sidewi = false;
					boolean sideni = false;
					boolean sideesi = false;
					boolean sidewsi = false;
					boolean sideeni = false;
					boolean sidewni = false;
					boolean sideel = false;
					boolean sideer = false;
					boolean sidesl = false;
					boolean sidesr = false;
					boolean sidewl = false;
					boolean sidewr = false;
					boolean sidenl = false;
					boolean sidenr = false;
					
					// 邻
					if (y > minY) {
						int rgb2 = buffImg.getRGB(x, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							siden = true;
						}
					} else {
						siden = true;
					}
					if (y < height - 1) {
						int rgb2 = buffImg.getRGB(x, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sides = true;
						}
					} else {
						sides = true;
					}
					if (x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidew = true;
						}
					} else {
						sidew = true;
					}
					if (x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidee = true;
						}
					} else {
						sidee = true;
					}
					
					// 间邻
					if (y > minY + 1) {
						int rgb2 = buffImg.getRGB(x, y - 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideni = true;
						}
					}
					if (y < height - 2) {
						int rgb2 = buffImg.getRGB(x, y + 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidesi = true;
						}
					}
					if (x > minX + 1) {
						int rgb2 = buffImg.getRGB(x - 2, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewi = true;
						}
					}
					if (x < width - 2) {
						int rgb2 = buffImg.getRGB(x + 2, y);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideei = true;
						}
					}
					
					// 斜邻
					if (y > minY && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewn = true;
						}
					} else {
						sidewn = true;
					}
					if (y < height - 1 && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidews = true;
						}
					} else {
						sidews = true;
					}
					if (y > minY && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideen = true;
						}
					} else {
						sideen = true;
					}
					if (y < height - 1 && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidees = true;
						}
					} else {
						sidees = true;
					}
					
					// 斜正隔
					if (y > minY + 1 && x > minX + 1) {
						int rgb2 = buffImg.getRGB(x - 2, y - 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewni = true;
						}
					}
					if (y < height - 2 && x > minX + 1) {
						int rgb2 = buffImg.getRGB(x - 2, y + 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewsi = true;
						}
					}
					if (y > minY + 1 && x < width - 2) {
						int rgb2 = buffImg.getRGB(x + 2, y - 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideeni = true;
						}
					}
					if (y < height - 2 && x < width - 2) {
						int rgb2 = buffImg.getRGB(x + 2, y + 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideesi = true;
						}
					}
					
					// 斜斜隔
					if (y > minY && x > minX + 1) {
						int rgb2 = buffImg.getRGB(x - 2, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewr = true;
						}
					}
					if (y > minY + 1 && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y - 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidenl = true;
						}
					}
					if (y < height - 1 && x > minX + 1) {
						int rgb2 = buffImg.getRGB(x - 2, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidewl = true;
						}
					}
					if (y < height - 2 && x > minX) {
						int rgb2 = buffImg.getRGB(x - 1, y + 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidesr = true;
						}
					}
					if (y > minY + 1 && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y - 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidenr = true;
						}
					}
					if (y > minY && x < width - 2) {
						int rgb2 = buffImg.getRGB(x + 2, y - 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideel = true;
						}
					}
					if (y < height - 1 && x < width - 2) {
						int rgb2 = buffImg.getRGB(x + 2, y + 1);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sideer = true;
						}
					}
					if (y < height - 2 && x < width - 1) {
						int rgb2 = buffImg.getRGB(x + 1, y + 2);
	                	Color color2 = new Color(rgb2); // 根据rgb的int值分别取得r,g,b颜色。
	                	if (color2.getRed() < 180 || color2.getGreen() < 180 || color2.getBlue() < 180) {
							sidesl = true;
						}
					}
					
					// 西西南
					if(sidewi && !sidew 
							&& sidewl && sidews && sides 
							&& !sidewr && !sidewn && !siden 
							&& !sidewni && !sidenl && !sideni 
							&& !sideeni && !sidenr 
							&& !sideen && !sideel 
							&& !sidee && !sideei 
							&& !sidees && !sideer
							&& !sidesl && !sideesi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 西西北
					if(sidewi && !sidew 
							&& sidewr && sidewn && siden 
							&& !sidewl && !sidews && !sides 
							&& !sidewsi && !sidesr && !sidesi 
							&& !sideeni && !sidenr 
							&& !sideen && !sideel 
							&& !sidee && !sideei 
							&& !sidees && !sideer
							&& !sidesl && !sideesi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 东东北
					if(sideei && !sidee 
							&& sideel && sideen && siden 
							&& !sideer && !sidees && !sides 
							&& !sideesi && !sidesl && !sidesi 
							&& !sidewsi && !sidesr 
							&& !sidews && !sidewl 
							&& !sidew && !sidewi 
							&& !sidewn && !sidewr
							&& !sidenl && !sidewni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 东东南
					if(sideei && !sidee 
							&& sideer && sidees && sides 
							&& !sideel && !sideen && !siden 
							&& !sideeni && !sidenr && !sideni 
							&& !sidewsi && !sidesr 
							&& !sidews && !sidewl 
							&& !sidew && !sidewi 
							&& !sidewn && !sidewr
							&& !sidenl && !sidewni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 北西北
					if(sideni && !siden 
							&& sidenl && sidewn && sidew 
							&& !sidenr && !sideen && !sidee 
							&& !sideeni && !sideel && !sideei 
							&& !sideesi && !sideer 
							&& !sidees && !sidesl 
							&& !sides && !sidesi 
							&& !sidews && !sidesr
							&& !sidewl && !sidewsi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 北东北
					if(sideni && !siden 
							&& sidenr && sideen && sidee 
							&& !sidenl && !sidewn && !sidew 
							&& !sidewni && !sidewr && !sidewi 
							&& !sideesi && !sideer 
							&& !sidees && !sidesl 
							&& !sides && !sidesi 
							&& !sidews && !sidesr
							&& !sidewl && !sidewsi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 南东南
					if(sidesi && !sides 
							&& sidesl && sidees && sidee 
							&& !sidesr && !sidews && !sidew 
							&& !sidewsi && !sidewl && !sidewi 
							&& !sidewni && !sidewr 
							&& !sidewn && !sidenl 
							&& !siden && !sideni 
							&& !sideen && !sidenr
							&& !sideel && !sideeni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 南西南
					if(sidesi && !sides 
							&& sidesr && sidews && sidew 
							&& !sidesl && !sidees && !sidee 
							&& !sideesi && !sideer && !sideei 
							&& !sidewni && !sidewr 
							&& !sidewn && !sidenl 
							&& !siden && !sideni 
							&& !sideen && !sidenr
							&& !sideel && !sideeni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
						
					// 西北
					if (sidewn && sidew && siden && !sidee && !sides && !sidews && !sideen && !sidees && (sidewl || sidenr) && !sidewni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 西南
					if (sidews && sidew && sides && !sidee && !siden && !sidewn && !sideen && !sidees && (sidewr || sidesl) && !sidewsi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 东北
					if (sideen && sidee && siden && !sidew && !sides && !sidees && !sidewn && !sidews && (sideer || sidenl) && !sideeni) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
					// 东南
					if (sidees && sidee && sides && !sidew && !siden && !sideen && !sideen && !sidews && (sideel || sidesr) && !sideesi) {
						buffImg.setRGB(x, y, Color.WHITE.getRGB());
					}
                }
            }
        }
	}
    
	
	private static class Boundary {
		int minX = -1;
		int minY = -1;
		int maxX = -1;
		int maxY = -1;

		int getWidth() {
			return maxX - minX + 1;
		}

		int getHeight() {
			return maxY - minY + 1;
		}
	}

	public static void main(String[] args) {
		//System.out.println(Color.WHITE.getRGB());
		//System.out.println(Color.BLACK.getRGB());
	    /*File[] files = new File("tesseract").listFiles(new FilenameFilter(){
            public boolean accept(File dir, String name) {
                if(name.endsWith(".png")) {
                    return true;
                }
                return false;
            }
	    });
	    for (File file : files) {
	        System.out.println(read(file.getName()));
	    }*/
	    System.out.println(read("1359375892201.png"));
	}

}
